<?php
/*
 * description：
 * author：wh
 * email：
 * createTime：{2024/6/28} {15:11} 
 */

namespace wanghua\general_utility_tools_php\alibaba\distributes\strict;

use Exception;
use wanghua\general_utility_tools_php\http\Curl;
use wanghua\general_utility_tools_php\alibaba\distributes\BaseStrict;

/**
 * 分销订单
 * Class Order
 * @package app\index\logic\alibaba\distributes
 */
class StrictOrder extends BaseStrict
{
    //用户收货地址
    private $address = [];
    //商品信息
    private $goods = [];
    //发票信息
    private $invoice = [];
    //交易类型 由于不同的商品支持的交易方式不同，没有一种交易方式是全局通用的，所以当前下单可使用的交易方式必须通过下单预览接口的tradeModeNameList获取。
    public $tradeType = '';

    /**
     * desc：收货地址说明
    1、使用保存的收货地址传参示例：{"addressId":593861699}，其中addressId是调用“买家获取保存的收货地址信息列表”接口获取；
    2、使用地址编码传参示例：{"address":"桃浦镇 金达路888号贸易8楼","phone": "0517-88990077","mobile": "15251667788","fullName": "张三","postCode": "000000","districtCode": "310107"}，其中districtCode需要调用“根据地址解析地区码”接口获取；
    3、直接使用文本地址示例：{"address":"网商路699号","phone": "0517-88990077","mobile": "15251667788","fullName": "张三","postCode": "000000","areaText": "滨江区","townText": "","cityText": "杭州市","provinceText": "浙江省"}，省市区要传文本；
    4、优先级说明，如果同时传入以上参数，系统按从1至3的优先级获取地址，满足1的条件下不会使用上示2中的参数，满足2的条件下不会使用上示3中的参数；
     * author：wh
     * @param $address
     */
    function setAddress($address){
        //{
        //"address":"网商路699号",
        //"phone":"0517-88990077",
        //"mobile":"15251667788",
        //"fullName":"张三",
        //"postCode":"000000",
        //"areaText":"滨江区",
        //"townText":"",
        //"cityText":"杭州市",
        //"provinceText":"浙江省"
        //}
        //用户收货地址
        $this->address = [
            //'addressId'=>$address['id'],
            'address'=>$address['address'],//街道地  网商路699号
            'phone'=>$address['mobile'],//电话 0517-88990077
            'mobile'=>$address['mobile'],//手机
            'fullName'=>$address['name'],
            'postCode'=>'000000',//邮编 000000
            'areaText'=>$address['area'],//区文本
            'townText'=>$address['town'],//镇文本
            'cityText'=>$address['city'],//市文本
            'provinceText'=>$address['provice'],//省份文本
            //'districtCode'=>'000000',//地址编码	 310107
        ];

    }
    function setGoods($goods,$buy_num){
        $this->goods = [
            'offerId'=>$goods['offerid'],
            'quantity'=>$buy_num,//$goods['quantity'],//商品数量(计算金额用)
        ];
        if(!empty($goods['specid'])){
            $this->goods['specId'] = $goods['specid'];//商品规格id
        }
    }

    /**
     * desc：设置发票信息
     * author：wh
     */
    function setInvoice(array $invoice){
        $this->invoice = $invoice;
    }

    /**
     * desc：创建分销订单 下单
     *
     * 获取订单运费，请调用预览订单接口 alibaba.createOrder.preview
     *
     * 【优先推荐】
     * 优先推荐(适用于大部分场景):如果渠道服务的用户在采购过程中，价格是核心决策点，推荐直接使用接口中的"最优价下单“能力，即在订单预览、下单过程中选择flow为空，1688会在所有买家可下单的流程中选择最优价进行下单;
     * 如果渠道服务的对象以代发群体为主(例如淘卖)，需要依赖包邮服务，在分销严选商品下单时，fow选择【boutiquefenxiao】下单，这样即使在采购多件时依然能够保证包邮、48小时发货、7天无理由以及极速退款服务;
     * 如果渠道服务对象以批发群体为主(例如跨境)，对干是否包,邮的服务不是特别敏感，在分销严选商品下单时，fow选择[boutiquepifa】进行下单，使用该接口时，如果只单笔订单购买一件，依然以包邮价进行下单，在单笔多件时会自动切换为批发价+邮费的模式下单，
     *
     * @param $order
     * @param string $flow 下单时必填 boutiquefenxiao(新分销严选包邮) boutiquepifa(分销批发)
     * author：wh
     */
    function createOrder($order,$flow){
        if(empty($this->authObj)){
            throw new Exception('未初始化授权对象');
        }
        if(empty($this->address)){
            throw new Exception('未设置收货地址');
        }
        if(empty($this->goods)){
            throw new Exception('未设置商品信息');
        }
        //$base_url = "https://gw.open.1688.com/openapi/";
        $urlPath = "param2/1/com.alibaba.trade/alibaba.trade.fastCreateOrder/".$this->authObj->config['appkey'];

        if(empty($this->tradeType)){
            throw new Exception('交易类型必须');
        }
        //由于不同的商品支持的交易方式不同，没有一种交易方式是全局通用的，
        //所以当前下单可使用的交易方式必须通过下单预览接口的tradeModeNameList获取。
        $request_data = ['tradeType'=>$this->tradeType];

        //boutiquefenxiao(新分销严选)
        $request_data['flow'] = $flow;//'boutiquefenxiao';
        $request_data['isvBizTypeStr'] = 'fenxiaoMedia';

        $request_data['message'] = $order['remark'];//买家留言
        //地址
        $request_data['addressParam'] = json_encode($this->address,JSON_UNESCAPED_UNICODE);
        //商品信息
        $request_data['cargoParamList'] = json_encode($this->goods,JSON_UNESCAPED_UNICODE);
        //发票信息
        $request_data['invoiceParam'] = json_encode($this->invoice,JSON_UNESCAPED_UNICODE);

        $res = $this->authObj->request($urlPath, $request_data);
        return $res;
    }

    /**
     * 创建订单前预览数据接口
     *
     * 【下单的时候flow是必填的。只有在预览的时候不填写flow会返回最优的下单方式】
     * 【调用预览接口，这个是最准确的。】
     *
     * 订单创建只允许购买同一个供应商的商品。
     * 本接口返回创建订单相关的优惠等信息。
     * 1、校验商品数据是否允许订购。 2、校验代销关系 3、校验库存、起批量、是否满足混批条件
     *
     * doc: https://open.1688.com/api/apidocdetail.htm?id=com.alibaba.trade:alibaba.createOrder.preview-1&aopApiCategory=trade_new
     */
    function previewOrder($flow=''){
        $urlPath = "param2/1/com.alibaba.trade/alibaba.createOrder.preview/".$this->authObj->config['appkey'];
        $request_data = [];
        //boutiquefenxiao(新分销严选)
        $request_data['flow'] = $flow;//'boutiquefenxiao';
        //$request_data['isvBizTypeStr'] = 'fenxiaoMedia';

        //$request_data['message'] = $order['remark'];//买家留言
        //地址
        $request_data['addressParam'] = json_encode($this->address,JSON_UNESCAPED_UNICODE);
        //商品信息
        $request_data['cargoParamList'] = json_encode($this->goods,JSON_UNESCAPED_UNICODE);
        //发票信息
        $request_data['invoiceParam'] = json_encode($this->invoice,JSON_UNESCAPED_UNICODE);

        $res = $this->authObj->request($urlPath, $request_data);
        return $res;
    }

    /**
     * 取消交易
     *
     * 买家或者卖家取消交易，注意只有特定状态的交易才能取消，1688可用于取消未付款的订单。
     *
     * doc: https://open.1688.com/api/apidocdetail.htm?id=com.alibaba.trade:alibaba.trade.cancel-1&aopApiCategory=trade_new
     *
     * author：wh
     * @param string $order_id 订单号
     * @param string $cancelReason 原因描述；buyerCancel:买家取消订单;sellerGoodsLack:卖家库存不足;other:其它
     *
     * 返回：{
    "success": true
    }
     */
    function cancelOrder($order_id, $cancelReason, $remark=''){
        $urlPath = "param2/1/com.alibaba.trade/alibaba.trade.cancel/".$this->authObj->config['appkey'];
        $request_data = [];
        $request_data['tradeID'] = $order_id;
        $request_data['webSite'] = 1688;
        //原因描述；buyerCancel:买家取消订单;sellerGoodsLack:卖家库存不足;other:其它
        $request_data['cancelReason'] = $cancelReason;
        if($remark){
            $request_data['remark'] = $remark;
        }
        $res = $this->authObj->request($urlPath, $request_data);
        return $res;
    }

    /**
     * 修改订单备忘
     *
     * 授权用户为卖家修改卖家备忘，授权用户为买家修改买家备忘 注意：该接口可重复调用，备注内容将覆盖前一次调用
     *
     * doc: https://open.1688.com/api/apidocdetail.htm?id=com.alibaba.trade:alibaba.order.memoAdd-1&aopApiCategory=trade_new
     *
     */
    function updateOrderRemark($order_id,$remark){
        $urlPath = "param2/1/com.alibaba.trade/alibaba.order.memoAdd/".$this->authObj->config['appkey'];
        $request_data = [];
        $request_data['orderId'] = $order_id;
        $request_data['memo'] = $remark;
        //备忘图标，目前仅支持数字。1位红色图标，2为蓝色图标，3为绿色图标，4为黄色图标
        $request_data['remarkIcon'] = 2;

        $res = $this->authObj->request($urlPath, $request_data);
        return $res;
    }

    /**
     * 根据地址解析地区码
     *
     * 根据地址信息，解析地区码
     *
     * doc:https://open.1688.com/api/apidocdetail.htm?id=com.alibaba.trade:alibaba.trade.addresscode.parse-1&aopApiCategory=trade_new
     *
     *返回：{
    "result":  {
    "address":  "网商路699号",
    "addressCode":  "330108",
    "isDefault":  false,
    "latest":  false,
    "postCode":  "310051"
    }
    }
     */
    function getAreaCode($address){
        $urlPath = "param2/1/com.alibaba.trade/alibaba.trade.addresscode.parse/".$this->authObj->config['appkey'];
        $request_data = [];
        //地址信息 eg: 浙江省 杭州市 滨江区网商路699号
        $request_data['addressInfo'] = $address;

        $res = $this->authObj->request($urlPath, $request_data);
        return $res;
    }

    /**
     * 获取交易地址代码表详情
     *
     * 获取交易地址代码表，该API会返回输入code的详情和该code的下一级地区code.
     *
     * doc: https://open.1688.com/api/apidocdetail.htm?id=com.alibaba.trade:alibaba.trade.addresscode.get-1&aopApiCategory=trade_new
     *
     * 返回：{
    "result": {
    "code": "330108",
    "name": "滨江区",
    "parentCode": "330100",
    "post": "310051",
    "children": ["330108001",
    "330108002",
    "330108003"]
    }
    }
     */
    function getAreaCodeDetail($areaCode){
        $urlPath = "param2/1/com.alibaba.trade/alibaba.trade.addresscode.get/".$this->authObj->config['appkey'];
        $request_data = [];
        //地址code码 eg: 330108
        $request_data['areaCode'] = $areaCode;
        $request_data['webSite'] = 1688;

        $res = $this->authObj->request($urlPath, $request_data);
        return $res;
    }

    /**
     * 订单列表查看(买家视角)
     * https://open.1688.com/api/apidocdetail.htm?id=com.alibaba.trade:alibaba.trade.getBuyerOrderList-1&aopApiCategory=trade_new
     *
     */
    function getOrderList($queryParams=[],$page=1,$pageSize=20){
        $urlPath = "param2/1/com.alibaba.trade/alibaba.trade.getSellerOrderList/".$this->authObj->config['appkey'];
        $request_data = [];
        $request_data['page'] = $page;
        $request_data['pageSize'] = $pageSize;

        //业务类型，支持： "cn"(普通订单类型), "ws"(大额批发订单类型), "yp"(普通拿样订单类型), "yf"(一分钱拿样订单类型),
        // "fs"(倒批(限时折扣)订单类型), "cz"(加工定制订单类型), "ag"(协议采购订单类型), "hp"(伙拼订单类型),
        // "gc"(国采订单类型), "supply"(供销订单类型), "nyg"(nyg订单类型), "factory"(淘工厂订单类型),
        // "quick"(快订下单), "xiangpin"(享拼订单), "nest"(采购商城-鸟巢), "f2f"(当面付), "cyfw"(存样服务),
        // "sp"(代销订单标记), "wg"(微供订单), "factorysamp"(淘工厂打样订单), "factorybig"(淘工厂大货订单)
        if(isset($queryParams['bizTypes'])){
            $request_data['bizTypes'] = $queryParams['bizTypes'];
        }
        //下单开始时间 20180802211113000+0800
        if(isset($queryParams['createStartTime'])){
            $request_data['createStartTime'] = $queryParams['createStartTime'];
        }
        //下单结束时间 20180802211113000+0800
        if(isset($queryParams['createEndTime'])){
            $request_data['createEndTime'] = $queryParams['createEndTime'];
        }
        //是否查询历史订单表,默认查询当前表，即默认值为false
        if(isset($queryParams['isHis'])){
            $request_data['isHis'] = $queryParams['isHis'];
        }
        //查询修改时间结束 20180802211113000+0800
        if(isset($queryParams['modifyStartTime'])){
            $request_data['modifyStartTime'] = $queryParams['modifyStartTime'];
        }
        //查询修改时间结束 20180802211113000+0800
        if(isset($queryParams['modifyEndTime'])){
            $request_data['modifyEndTime'] = $queryParams['modifyEndTime'];
        }
        //订单状态，值有 success, cancel(交易取消，违约金等交割完毕), waitbuyerpay(等待卖家付款)，
        // waitsellersend(等待卖家发货),waitbuyerreceive(等待买家收货 )
        if(isset($queryParams['orderStatus'])){
            $request_data['orderStatus'] = $queryParams['orderStatus'];
        }
        //查询分页页码，从1开始
        //if(isset($queryParams['page'])){
        //    $request_data['page'] = $queryParams['page'];
        //}
        ////查询的每页的数量 20
        //if(isset($queryParams['pageSize'])){
        //    $request_data['pageSize'] = $queryParams['pageSize'];
        //}
        //退款状态，支持： "waitselleragree"(等待卖家同意), "refundsuccess"(退款成功), "refundclose"(退款关闭),
        // "waitbuyermodify"(待买家修改), "waitbuyersend"(等待买家退货), "waitsellerreceive"(等待卖家确认收货)
        if(isset($queryParams['refundStatus'])){
            $request_data['refundStatus'] = $queryParams['refundStatus'];
        }
        //卖家memberId b2b-1624961198
        if(isset($queryParams['sellerMemberId'])){
            $request_data['sellerMemberId'] = $queryParams['sellerMemberId'];
        }
        //卖家loginId alitestforisv02
        if(isset($queryParams['sellerLoginId'])){
            $request_data['sellerLoginId'] = $queryParams['sellerLoginId'];
        }
        //卖家评价状态 (4:已评价,5:未评价,6;不需要评价)
        if(isset($queryParams['sellerRateStatus'])){
            $request_data['sellerRateStatus'] = $queryParams['sellerRateStatus'];
        }
        //交易类型: 担保交易(1), 预存款交易(2), ETC境外收单交易(3), 即时到帐交易(4), 保障金安全交易(5), 统一交易流程(6),
        // 分阶段交易(7), 货到付款交易(8), 信用凭证支付交易(9), 账期支付交易(10), 1688交易4.0，新分阶段交易(50060),
        // 当面付的交易流程(50070), 服务类的交易流程(50080)
        if(isset($queryParams['tradeType'])){
            $request_data['tradeType'] = $queryParams['tradeType'];
        }
        //商品名称
        if(isset($queryParams['productName'])){
            $request_data['productName'] = $queryParams['productName'];
        }
        //是否需要查询买家的详细地址信息和电话 false
        if(isset($queryParams['needBuyerAddressAndPhone'])){
            $request_data['needBuyerAddressAndPhone'] = $queryParams['needBuyerAddressAndPhone'];
        }
        //是否需要查询备注信息 false
        if(isset($queryParams['needMemoInfo'])){
            $request_data['needMemoInfo'] = $queryParams['needMemoInfo'];
        }
        //外部订单号，可用于控制幂等 90187872898371
        if(isset($queryParams['outOrderId'])){
            $request_data['outOrderId'] = $queryParams['outOrderId'];
        }

        $res = $this->authObj->request($urlPath, $request_data);
        return $res;
    }
    /**
     * 订单详情查看(买家视角)
     * https://open.1688.com/api/apidocdetail.htm?id=com.alibaba.trade:alibaba.trade.get.buyerView-1&aopApiCategory=trade_new
     */
    function getBuyerView(int $orderId,$webSite='1688',$includeFields='',$attributeKeys='',$outOrderId=''){
        $urlPath = "param2/1/com.alibaba.trade/alibaba.trade.get.buyerView/".$this->authObj->config['appkey'];
        $request_data = [];
        $request_data['orderId'] = $orderId;//交易的订单id 1234345
        $request_data['webSite'] = $webSite;//站点信息，指定调用的API是属于国际站（alibaba）还是1688网站（1688）
        $request_data['includeFields'] = $includeFields;//查询结果中包含的域，GuaranteesTerms：保障条款，NativeLogistics：物流信息，RateDetail：评价详情，OrderInvoice：发票信息。默认返回GuaranteesTerms、NativeLogistics、OrderInvoice。
        $request_data['attributeKeys'] = $attributeKeys;//垂直表中的attributeKeys
        $request_data['outOrderId'] = $outOrderId;//外部订单id，控制幂等
        $res = $this->authObj->request($urlPath, $request_data);
        return $res;
    }

    /**
     * 获取交易订单的物流信息(买家视角)
     *
     * 该接口需要获得订单买家的授权，获取买家的订单的物流详情，在采购或者分销场景中，作为买家也有获取物流详情的需求。
     * 该接口能查能根据订单号查看物流详情，包括发件人，收件人，所发货物明细等。由于物流单录入的原因，
     * 可能跟踪信息的API查询会有延迟。该API需要向开放平台申请权限才能访问。
     *
     * https://open.1688.com/api/apidocdetail.htm?id=com.alibaba.logistics:alibaba.trade.getLogisticsInfos.buyerView-1&aopApiCategory=Logistics_NEW
     */
    function getLogisticsInfosBuyerView(int $orderId,$webSite='1688',$fields=''){
        $urlPath = "param2/1/com.alibaba.logistics/alibaba.trade.getLogisticsInfos.buyerView/".$this->authObj->config['appkey'];
        $request_data = [];
        $request_data['orderId'] = $orderId;//交易的订单id 1234345
        $request_data['webSite'] = $webSite;//站点信息，指定调用的API是属于国际站是1688业务还是icbu业务	(1688或者alibaba)
        $request_data['fields'] = $fields;//需要返回的字段，目前有:company.name,sender,receiver,sendgood。返回的字段要用英文逗号分隔开
        $res = $this->authObj->request($urlPath, $request_data);
        return $res;
    }
    /**
     * 获取交易订单的物流跟踪信息(买家视角)
     *
     * 该接口需要获取订单买家的授权，获取买家的订单的物流跟踪信息，在采购或者分销场景中，作为买家也有获取物流详情的需求。
     * 该接口能查能根据物流单号查看物流单跟踪信息。由于物流单录入的原因，可能跟踪信息的API查询会有延迟。
     * 该API需要向开放平台申请权限才能访问。
     *
     * https://open.1688.com/api/apidocdetail.htm?id=com.alibaba.logistics:alibaba.trade.getLogisticsTraceInfo.buyerView-1&aopApiCategory=Logistics_NEW
     */
    function getLogisticsTraceInfoBuyerView(int $orderId,$webSite='1688',$logisticsId=''){
        $urlPath = "param2/1/com.alibaba.logistics/alibaba.trade.getLogisticsTraceInfo.buyerView/".$this->authObj->config['appkey'];
        $request_data = [];
        $request_data['orderId'] = $orderId;//交易的订单id 1234345
        $request_data['webSite'] = $webSite;//站点信息，指定调用的API是属于国际站是1688业务还是ic
        $request_data['logisticsId'] = $logisticsId;//该订单下的物流编号 AL8234243
        $res = $this->authObj->request($urlPath, $request_data);
        return $res;
    }

    /**
     * 买家确认收货
     *
     * doc:https://open.1688.com/api/apidocdetail.htm?id=com.alibaba.trade:trade.receivegoods.confirm-1
     */
    function receiveGoodsConfirm(int $orderId,$orderEntryIds=[]){
        $urlPath = "param2/1/com.alibaba.trade/trade.receivegoods.confirm/".$this->authObj->config['appkey'];
        $request_data = [];
        $request_data['orderId'] = $orderId;//交易的订单id 1234345
        if($orderEntryIds){
            $request_data['orderEntryIds'] = json_encode($orderEntryIds,JSON_UNESCAPED_UNICODE);
        }
        $res = $this->authObj->request($urlPath, $request_data);
        return $res;
    }

}